package p3.ejemplos;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * Complementos de Informática. Práctica 3.
 * Cliente remoto. Pide un fichero y lo muestra en una ventana 
 * a medida que lo va recibiendo.
 * @author JAPF
 *
 */
public class ClienteRemoto extends JFrame implements ActionListener {
	
	private static final long serialVersionUID = 4467223450798880000L;
	protected String hostIp;
	protected int    hostPort;
	
	Socket cliente;
	protected BufferedReader socketReader;
	protected PrintWriter    socketWriter;
	
	protected volatile int rC  = 0;
	protected int numberOfTexts = 3;
	protected JScrollPane textPane;
	protected JTextArea textArea;
	protected JButton btRequest;
	protected JButton btClean;
	
	
	/**
	 * Crea cliente remoto.
	 * @param hostIp Dirección IP del servidor.
	 * @param port   Puerto del servidor.
	 */
	public ClienteRemoto(String hostIp, int port){		
		super("Cliente Remoto ");

		this.hostIp   = hostIp;
		this.hostPort = port;
		
		JPanel textPanel = new JPanel();
		textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.LINE_AXIS));
		
		textPanel.add(Box.createRigidArea(new Dimension(1, 0)));

		textArea = new JTextArea();
		textPane = new JScrollPane(textArea);
		textPanel.add(textPane);
		textPanel.add(Box.createRigidArea(new Dimension(1, 0)));
		
		JPanel btPanel = new JPanel();
		btRequest = new JButton("Request Text ");
		btRequest.addActionListener(this);
		btClean = new JButton("clean Text ");
		btClean.addActionListener(this);
		btPanel.add(btRequest);
		btPanel.add(btClean);
		
		getContentPane().add(btPanel, BorderLayout.NORTH);
		getContentPane().add(textPanel);
		
		setSize (390,680);
		setVisible(true);  
		validate();
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 	
	}
	
	/**
	 * Establece conexión con servidor.
	 * @return socket cliente conectado al servidor.
	 */
	public Socket establecerConexion(){
		Socket cliente = null;
		try{
			cliente = new Socket(Inet4Address.getLocalHost(), hostPort);
		}
		catch(UnknownHostException uhe){
			System.out.println("establecerConexion: " + uhe.getMessage());
		}
		catch(IOException ioe){
			System.out.println("establecerConexion: " + ioe.getMessage());			
		}
		return cliente;
	}
	
	/**
	 * Manda la petición de fichero, lee los datos recibidos y los muestra en
	 * el área de texto de la ventana.
	 * @param nombreFichero	Nombre del fichero pedido al servidor.
	 * @param s socket cliente conectado al servidor.
	 * @return Contenido del fichero leído.
	 */
	public String leerFichero(String nombreFichero, Socket s){

		StringBuffer lineasFichero = new StringBuffer();
		
		try {
			
			socketReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
			socketWriter = new PrintWriter(s.getOutputStream());
			
			// Se envía petición de servicio.
			socketWriter.println(nombreFichero);
			
			// Se vacía el buffer, forzando a que los datos se envíen al servidor
			// antes de que se cierre el socket.
			socketWriter.flush();

			// Se recogen los datos.
			String linea = null;
			while((linea = socketReader.readLine()) != null){
				lineasFichero.append(linea + "\n");
				textArea.append(linea + "\n");
				System.out.println(linea);
			}
			
			// Se cierra conexión.
			socketWriter.close();
			socketReader.close();
			s.close();
		}
		catch(IOException ioe){
			System.out.println("leerFichero: " + ioe.getMessage());				
		}
		return lineasFichero.toString();
	}
	
	
	public void actionPerformed(ActionEvent ae){
		// Crea petición y la manda.
		if (ae.getSource() == btRequest){
			System.out.println();
			System.out.println("\n\nCliente. Pidiendo fichero \n" + (rC + 1));
			textArea.append("\n\nCliente. Pidiendo fichero \n" + (rC + 1) + "\n\n");
			System.out.println();
                        //En Windows
//			String fich = "C:\\Ej" + (rC+1) + ".txt";
                        //En linux en casa
                        String fich = "/home/clara/Ej" + (rC+1) + ".txt";
			
			// Establece conexión con el servidor.
			// ATENCIÓN: Cada petición de servicio se hace en una nueva conexión.
			cliente = establecerConexion();
			
			// Manda petición y muestra datos recibidos.
			new Thread(new ReaderFile(fich, cliente)).start();
			//leerFichero(fich, cliente);
			rC = (rC + 1) % numberOfTexts;
		}
		
		// Limpia área de texto.
		if (ae.getSource() == btClean){
            textArea.setText(null);
		}
	}
	

    /**
     * Pide fichero, recibe su contenido y lo muestra a medida que
     * lo recibe. 
     * @author JAPF
     *
     */
    public class ReaderFile implements Runnable  {
    	
    	String fichero;
    	Socket s;
    	
    	/**
    	 * Crea el lector del fichero.
    	 * @param f Fichero a pedir.
    	 * @param cliente socket conectado al servidor.
    	 */
    	public ReaderFile(String f, Socket cliente){
    		fichero = f;		
    		s = cliente;
    	}
    	
    	/**
    	 * Manda la petición de fichero, lee los datos recibidos y los muestra en
    	 * el área de texto de la ventana.
    	 * @param nombreFichero	Nombre del fichero pedido al servidor.
    	 * @return Contenido del fichero le�do.
    	 */
    	public String leerFichero(String nombreFichero){

    		StringBuffer lineasFichero = new StringBuffer();
    		
    		try {
    			
    			socketReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
    			socketWriter = new PrintWriter(s.getOutputStream());
    			
    			// Se env�a petición de servicio.
    			socketWriter.println(nombreFichero);
    			
    			// Se vac�a el buffer, forzando a que los datos se env�en al servidor
    			// antes de que se cierre el socket.
    			socketWriter.flush();

    			// Recogemos los datos.
    			String linea = null;
    			while((linea = socketReader.readLine()) != null){
    				lineasFichero.append(linea + "\n");
    				textArea.append(linea + "\n");
    				System.out.println(linea);
    			}
    			socketWriter.close();
    			socketReader.close();
    			s.close();
    		}
    		catch(IOException ioe){
    			System.out.println("leerFichero: " + ioe.getMessage());				
    		}
    		return lineasFichero.toString();
    	}
    	
    	public void run(){
    		leerFichero(fichero);
    	}
    }
	
	
	public static void main(String [] args){
		new ClienteRemoto("127.0.0.1", 3000);
	}
}


